package com.amu.aidemo.android.audio

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
import androidx.core.app.ActivityCompat
import kotlinx.coroutines.*
import kotlin.math.abs

private const val TAG = "AudioRecorder"

class AudioRecorder(private val context: Context) {
    
    companion object {
        const val SAMPLE_RATE = 16000 // 16kHz
        const val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO
        const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
        const val CHUNK_SIZE = 1280 // 80ms at 16kHz
    }

    private var audioRecord: AudioRecord? = null
    private var recordingJob: Job? = null
    private var isRecording = false

    // 回调
    var onAudioChunk: ((FloatArray) -> Unit)? = null
    var onError: ((String) -> Unit)? = null

    /**
     * 开始录音
     */
    fun startRecording() {
        if (isRecording) {
            Log.w(TAG, "Already recording")
            return
        }

        if (!checkPermission()) {
            onError?.invoke("没有录音权限")
            return
        }

        try {
            val bufferSize = AudioRecord.getMinBufferSize(
                SAMPLE_RATE,
                CHANNEL_CONFIG,
                AUDIO_FORMAT
            ).coerceAtLeast(CHUNK_SIZE * 2)

            audioRecord = AudioRecord(
                MediaRecorder.AudioSource.MIC,
                SAMPLE_RATE,
                CHANNEL_CONFIG,
                AUDIO_FORMAT,
                bufferSize
            )

            if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) {
                onError?.invoke("AudioRecord 初始化失败")
                return
            }

            audioRecord?.startRecording()
            isRecording = true

            // 在后台线程处理音频
            recordingJob = CoroutineScope(Dispatchers.IO).launch {
                processAudio()
            }

            Log.d(TAG, "Recording started")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start recording", e)
            onError?.invoke("启动录音失败: ${e.message}")
        }
    }

    /**
     * 停止录音
     */
    fun stopRecording() {
        if (!isRecording) {
            return
        }

        isRecording = false
        recordingJob?.cancel()
        recordingJob = null

        try {
            audioRecord?.stop()
            audioRecord?.release()
            audioRecord = null
            Log.d(TAG, "Recording stopped")
        } catch (e: Exception) {
            Log.e(TAG, "Error stopping recording", e)
        }
    }

    private suspend fun processAudio() {
        val buffer = ShortArray(CHUNK_SIZE)
        var chunkCount = 0
        
        while (isRecording && audioRecord != null) {
            val readSize = audioRecord?.read(buffer, 0, CHUNK_SIZE) ?: 0
            
            if (readSize > 0) {
                chunkCount++
                
                // 转换为 float 数组 (-1.0 到 1.0)
                val floatBuffer = FloatArray(readSize) { i ->
                    buffer[i] / 32768.0f
                }
                
                // 计算音量（每50帧打印一次）
                if (chunkCount % 50 == 0) {
                    val volume = calculateVolume(floatBuffer)
                    Log.v(TAG, "Audio chunk #$chunkCount, volume: ${String.format("%.4f", volume)}")
                }
                
                // 回调音频数据
                withContext(Dispatchers.Main) {
                    onAudioChunk?.invoke(floatBuffer)
                }
            } else if (readSize < 0) {
                Log.e(TAG, "Error reading audio: $readSize")
                break
            }
        }
        
        Log.d(TAG, "Audio processing stopped. Total chunks processed: $chunkCount")
    }

    /**
     * 检查录音权限
     */
    private fun checkPermission(): Boolean {
        return ActivityCompat.checkSelfPermission(
            context,
            Manifest.permission.RECORD_AUDIO
        ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 计算音频音量（用于可视化）
     */
    fun calculateVolume(audioData: FloatArray): Float {
        if (audioData.isEmpty()) return 0f
        
        var sum = 0.0
        for (sample in audioData) {
            sum += abs(sample.toDouble())
        }
        return (sum / audioData.size).toFloat()
    }

    /**
     * 释放资源
     */
    fun release() {
        stopRecording()
    }
}
